<?php
/**
* 名称：路由类。
* 描述：负责tryPHP中寻址、创行控制器。
*/
final class Route{
    /**
    * 描述：字面量常值。
    */
    const PROTOCOL_COMMON='common';             //路由协议之“默认协议”字面量常值。
    const PROTOCOL_STATIC='static';             //路由协议之“静态协议”的字面量常值。
    const INDEX_NAME_APPLICATION='application'; //参数集合中，用于索引“应用”的字面量值。
    const INDEX_NAME_CONTROLLER='controller';   //参数集合中，用于索引“控制器”的字面量值。
    const INDEX_NAME_METHOD='method';           //参数集合中，用于索引“控制器操作标识”的字面量值。
    const INDEX_NAME_MODE='mode';               //参数集合中，用于索引“控制器运行模式”的字面量值。

    /**
    * 描述：配置选项内部标量。
    */
    private static $Protocol=NULL;                                       //协议。
    private static $DefaultApplication=NULL;                             //默认应用。
    private static $DefaultController=NULL;                              //默认控制器。
    private static $ProtocolOptionsCommonParametersNameApplication=NULL; //应用。
    private static $ProtocolOptionsCommonParametersNameController=NULL;  //控制器。
    private static $ProtocolOptionsCommonParametersNameMethod=NULL;      //方法。
    private static $ProtocolOptionsCommonParametersNameMode=NULL;        //模式。

    /**
    * 描述：是否己经解析参数。
    */
    private static $IsParse=FALSE;

    /**
    * 描述：请求参数的集合。
    */
    private static $Arguments=array(
        self::INDEX_NAME_APPLICATION=>NULL,
        self::INDEX_NAME_CONTROLLER=>NULL,
        self::INDEX_NAME_METHOD=>NULL,
        self::INDEX_NAME_MODE=>NULL
    );
    /**
    * 描述：根据协议采用不同的方法获取值，并构建Route实例。
    */
    private static function ParseArguments(){
        self::$Protocol=strtolower(TRYPHP_ROUTE_PROTOCOL);
        self::$DefaultApplication=TRYPHP_DEFAULT_APPLICATION;
        self::$DefaultController=TRYPHP_DEFAULT_CONTROLLER;
        self::$ProtocolOptionsCommonParametersNameApplication=TRYPHP_ROUTE_PROTOCOLOPTIONS_COMMON_PARAMETERNAME_APPLICATION;
        self::$ProtocolOptionsCommonParametersNameController=TRYPHP_ROUTE_PROTOCOLOPTIONS_COMMON_PARAMETERNAME_CONTROLLER;
        self::$ProtocolOptionsCommonParametersNameMethod=TRYPHP_ROUTE_PROTOCOLOPTIONS_COMMON_PARAMETERNAME_METHOD;
        self::$ProtocolOptionsCommonParametersNameMode=TRYPHP_ROUTE_PROTOCOLOPTIONS_COMMON_PARAMETERNAME_MODE;
        #开始解析，并标注为己经解析。
        if(self::$IsParse===TRUE){
           return;
        }
        #开始初始化处理。
        if(self::PROTOCOL_STATIC===self::$Protocol){
            #路径偏移处理，就是当ROOT和BUILD_ROOT值不相等，也就是TryPHP架构根路径和PHP构架路径不相等的情况。
            if(BUILD_PATH_OFFSET){
                $arguments=explode('/',str_replace(BUILD_PATH_OFFSET,'',$_SERVER['REQUEST_URI']));
            }
            else{
                $arguments=explode('/',$_SERVER['REQUEST_URI']);
            }
            #应用参数处理。
            if(isset($arguments[1])&&!empty($arguments[1])){
                self::$Arguments[self::INDEX_NAME_APPLICATION]=$arguments[1];
            }
            else{
                self::$Arguments[self::INDEX_NAME_APPLICATION]=self::$DefaultApplication;
            }
            #控制器及其模式参数处理。
            if(isset($arguments[2])&&!empty($arguments[2])){
                if(FALSE!==strpos($arguments[2],'?')){ //处理DWZ加上去的随机字符串。
                    $temp=explode('?',$arguments[2]);
                    $arguments[2]=$temp[0];
                }
                if(strpos($arguments[2],'-')===FALSE){ //获析参数，取得controll和mode的值。
                    self::$Arguments[self::INDEX_NAME_CONTROLLER]=$arguments[2];
                    self::$Arguments[self::INDEX_NAME_MODE]=Controller::MODE_CLASS;
                }
                else{
                    $temp=explode('-',$arguments[2]);
                    self::$Arguments[self::INDEX_NAME_CONTROLLER]=$temp[0];
                    if(empty($temp[1])){
                        self::$Arguments[self::INDEX_NAME_MODE]=Controller::MODE_CLASS;
                    }
                    else{
                        self::$Arguments[self::INDEX_NAME_MODE]=$temp[1];
                    }
                }
            }
            else{
                self::$Arguments[self::INDEX_NAME_MODE]=Controller::MODE_CLASS;
                self::$Arguments[self::INDEX_NAME_CONTROLLER]=self::$DefaultController;
            }
            #调用方法参数处理。
            if(isset($arguments[3])&&!empty($arguments[3])){
                if(FALSE!==strpos($arguments[3],'&')){ //处理“&”符号的存在，“&”后面为无效字符。
                    $temp=explode('&',$arguments[3]);
                    $arguments[3]=$temp[0];
                }
                self::$Arguments[self::INDEX_NAME_METHOD]=$arguments[3];
            }
            else{
                self::$Arguments[self::INDEX_NAME_METHOD]=NULL;
            }
            #生成请求参数。
            $otherArguments=array_slice($arguments,4,count($arguments)-1);
            foreach($otherArguments as $key=>$value){
                if(strpos($value,'_')!==FALSE){
                    $temp=explode('_',$value);
                    self::$Arguments[$temp[0]]=$temp[1];
                }
                else{
                    self::$Arguments[$key]=$value;
                }
            }
        }
        else{
            $arguments=$_GET;
            #应用参数处理。
            $applicationParameterName=self::$ProtocolOptionsCommonParametersNameApplication;
            if(isset($arguments[$applicationParameterName])&&!empty($arguments[$applicationParameterName])){
                self::$Arguments[self::INDEX_NAME_APPLICATION]=$_GET[$applicationParameterName];
                unset($arguments[$applicationParameterName]);
            }
            else{
                self::$Arguments[self::INDEX_NAME_APPLICATION]=self::$DefaultApplication;
            }
            #控制器参数处理。
            $controllerParameterName=self::$ProtocolOptionsCommonParametersNameController;
            if(isset($arguments[$controllerParameterName])&&!empty($arguments[$controllerParameterName])){
                self::$Arguments[self::INDEX_NAME_CONTROLLER]=$arguments[$controllerParameterName];
                unset($arguments[$controllerParameterName]);
            }
            else{
                self::$Arguments[self::INDEX_NAME_CONTROLLER]=self::$DefaultController;
            }
            #控制器模式参数处理。
            $modeParameterName=self::$ProtocolOptionsCommonParametersNameMode;
            if(isset($arguments[$modeParameterName])&&!empty($arguments[$modeParameterName])){
                self::$Arguments[self::INDEX_NAME_MODE]=$arguments[$modeParameterName];
                unset($arguments[$modeParameterName]);
            }
            else{
                self::$Arguments[self::INDEX_NAME_MODE]=Controller::MODE_CLASS;
            }
            #控制器操作标识符参数处理。
            $methodParameterName=self::$ProtocolOptionsCommonParametersNameMethod;
            if(isset($arguments[$methodParameterName])&&!empty($arguments[$methodParameterName])){
                self::$Arguments[self::INDEX_NAME_METHOD]=$arguments[$methodParameterName];
                unset($arguments[$methodParameterName]);
            }
            #生成请求参数。
            foreach($arguments as $key=>$value){
                self::$Arguments[$key]=$value;
            }
        }
        self::$IsParse=TRUE;
    }

    /**
    * 描述：根据协议生成URL。
    */
    public static function GenerateURI($arguments){
        self::ParseArguments();
        #处理smarty调用。
        if('string'===gettype($arguments)){
            $tempArray=explode('|',$arguments);
            $arguments=array();
            foreach($tempArray as $value){
                $temp=explode(':',$value);
                $arguments[strtolower($temp[0])]=$temp[1];
            }
        }
        #开始生成URL。
        $url=NULL;
        if(self::PROTOCOL_STATIC===self::$Protocol){
            #app
            if(isset($arguments[self::INDEX_NAME_APPLICATION])){
                $url.='/'.$arguments[self::INDEX_NAME_APPLICATION];
            }
            else{
                $url.='/'.self::$DefaultApplication;
            }
            #controller
            if(isset($arguments[self::INDEX_NAME_CONTROLLER])){
                $url.='/'.$arguments[self::INDEX_NAME_CONTROLLER];
            }
            else{
                $url.='/'.self::$DefaultController;
            }
            #mode
            if(isset($arguments[self::INDEX_NAME_MODE])){
                $url.='-'.$arguments[self::INDEX_NAME_MODE];
            }
            #method
            if(isset($arguments[self::INDEX_NAME_METHOD])){
                $url.='/'.$arguments[self::INDEX_NAME_METHOD];
            }
            #path
            if(BUILD_PATH_OFFSET){
                $url=BUILD_PATH_OFFSET.$url;
            }
        }
        else{
            $url.='./?';
            #app
            if(isset($arguments[self::INDEX_NAME_APPLICATION])){
                $url.=(self::$ProtocolOptionsCommonParametersNameApplication.'='.$arguments[self::INDEX_NAME_APPLICATION]);
                unset($arguments[self::INDEX_NAME_APPLICATION]);
            }
            else{
                $url.=(self::$ProtocolOptionsCommonParametersNameApplication.'='.self::$DefaultApplication);
            }
            #controller
            if(isset($arguments[self::INDEX_NAME_CONTROLLER])){
                $url.=('&'.self::$ProtocolOptionsCommonParametersNameController.'='.$arguments[self::INDEX_NAME_CONTROLLER]);
                unset($arguments[self::INDEX_NAME_CONTROLLER]);
            }
            else{
                $url.=(self::$ProtocolOptionsCommonParametersNameController.'='.self::$DefaultController);
            }
            #mode
            if(isset($arguments[self::INDEX_NAME_MODE])){
                $url.=('&'.self::$ProtocolOptionsCommonParametersNameMode.'='.$arguments[self::INDEX_NAME_MODE]);
                unset($arguments[self::INDEX_NAME_MODE]);
            }
            #method
            if(isset($arguments[self::INDEX_NAME_METHOD])){
                $url.=('&'.self::$ProtocolOptionsCommonParametersNameMethod.'='.$arguments[self::INDEX_NAME_METHOD]);
                unset($arguments[self::INDEX_NAME_METHOD]);
            }
            #other
            foreach($arguments as $name=>$value){
                $url.=('&'.$name.'='.$value);
            }
        }
        return $url;
    }

    /**
    * 描述：获取请求的参数值。
    */
    public static function GetArguments($name){
        self::ParseArguments();
        $result=NULL;
        #处理callStatic调用。
        if('array'===gettype($name)){
            $name=$name[0];
        }
        #开始处理过程。
        if(array_key_exists($name,self::$Arguments)){
            $result=self::$Arguments[$name];
        }
        return $result;
    }

    /**
    * 描述：导向404文件。
    */
    public static function Http404($filePath){
        if(file_exists($filePath)){
            include($filePath);
        }
        header('HTTP/1.0 404 Not Found!');
    }
}
?>